package com.zmn.mcc.business.impl.staff.dingtalk;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.mcc.business.interfaces.staff.dingtalk.DingTalkService;
import com.zmn.mcc.common.constant.DingTalkConsts;
import com.zmn.mcc.common.dictionary.StaffArchivesDict;
import com.zmn.mcc.common.dictionary.StaffDict;
import com.zmn.mcc.common.dictionary.StaffFamilyDict;
import com.zmn.mcc.common.dto.dingtalk.RobotSendGroupMessage;
import com.zmn.mcc.common.dto.dingtalk.SendImageMessageResult;
import com.zmn.mcc.manager.utils.DingTalkUtil;
import com.zmn.mcc.model.entity.staff.DingTalkLeave;
import com.zmn.mcc.model.entity.staff.DingTalkResult;
import com.zmn.mcc.model.entity.staff.dingtalk.DingTalkIdAndMediaId;
import com.zmn.mcc.model.entity.staff.dingtalk.StaffDingTalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.net.URLEncoder;

@Service
public class DingTalkServiceImpl implements DingTalkService {

    @Resource
    DingTalkService dingTalkService;

    private Logger logger = LoggerFactory.getLogger(DingTalkServiceImpl.class);

    private static Long LAST_TIME = 0L;

    private static String CORP_ACCESS_TOKEN = null;

    //缓存时间调整到1小时50分钟
    private static final long CACHE_TIME = 1000 * 60 * 55 * 2;

    @Override
    public ResponseDTO<String> addDingDingUser(String realName, String mobile, Date preEntryTime) throws ApiException {
        try {
            String assessToken = dingTalkService.getDingTalkAccessToken();
            DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_ADD_EMP_URL);
            OapiSmartworkHrmEmployeeAddpreentryRequest req = new OapiSmartworkHrmEmployeeAddpreentryRequest();
            OapiSmartworkHrmEmployeeAddpreentryRequest.PreEntryEmployeeAddParam param = new OapiSmartworkHrmEmployeeAddpreentryRequest.PreEntryEmployeeAddParam();
            param.setName(realName);
            param.setMobile(mobile);
            param.setPreEntryTime(preEntryTime);
            req.setParam(param);
            OapiSmartworkHrmEmployeeAddpreentryResponse rsp = client.execute(req, assessToken);
            Map map = JSONObject.parseObject(rsp.getBody(), Map.class);
            if (Objects.equals(map.get("errcode"), 0)) {
                return ResponseDTO.success(map.get("userid").toString());
            } else {
                return ResponseDTO.success(null, map.get("errmsg").toString());
            }
        } catch (Exception e) {
            return ResponseDTO.fail("钉钉调用失败");
        }

    }

    @Override
    public ResponseDTO<String> updateDingDingUser(StaffDingTalk staffDingTalk) throws ApiException {
        try {
            String assessToken = dingTalkService.getDingTalkAccessToken();
            DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_UPDATE_STAFF_URL);
            OapiSmartworkHrmEmployeeUpdateRequest req = new OapiSmartworkHrmEmployeeUpdateRequest();
            OapiSmartworkHrmEmployeeUpdateRequest.PreEntryEmployeeAddParam param = new OapiSmartworkHrmEmployeeUpdateRequest.PreEntryEmployeeAddParam();
            param.setUserid(staffDingTalk.getDTalkId());
            List<OapiSmartworkHrmEmployeeUpdateRequest.GroupMetaInfo> groups = DingTalkUtil.objToDingTalkUpdateUserRequest(staffDingTalk);
            param.setGroups(groups);
            req.setParam(param);
            req.setAgentid(DingTalkConsts.DING_TALK_AGENT_ID);
            logger.info(JSON.toJSONString(req));
            OapiSmartworkHrmEmployeeUpdateResponse rsp = client.execute(req, assessToken);
            Map map = JSONObject.parseObject(rsp.getBody(), Map.class);
            if (Objects.equals(map.get("errcode"), 0)) {
                return ResponseDTO.success(staffDingTalk.getDTalkId());
            } else {
                return ResponseDTO.success(null, map.get("errmsg").toString());
            }
        } catch (Exception e) {
            return ResponseDTO.fail("钉钉调用失败");
        }
    }

    @Override
    @Cacheable(cacheNames = "redis1h", key = "'taobao:ding:talk:access:token'")
    public String getDingTalkAccessToken() throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_TOKEN_URL);
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(DingTalkConsts.DING_TALK_APP_KEY);
        request.setAppsecret(DingTalkConsts.DING_TALK_APP_SECRET);
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }

    @Override
    public String getSnsAccessToken() throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_SNS_TOKEN_URL);
        OapiSnsGettokenRequest request = new OapiSnsGettokenRequest();
        request.setAppid(DingTalkConsts.DD_APP_ID);
        request.setAppsecret(DingTalkConsts.DD_APP_SECRET);
        request.setHttpMethod("GET");
        OapiSnsGettokenResponse resp = client.execute(request);
        logger.info("第一步临时snsToken={}",resp.getAccessToken());
        return resp.getAccessToken();
    }

    @Override
//    @Cacheable(cacheNames = "redis1h", key = "'taobao:ding:talk:corp:access:token'")
    public String getCorpAccessToken() throws ApiException {
        Long curTime = System.currentTimeMillis();
        Long differ = curTime - LAST_TIME;
        //没有过期就使用已保存的
        if (null != CORP_ACCESS_TOKEN && differ < CACHE_TIME) {
            return CORP_ACCESS_TOKEN;
        }
        DefaultDingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_TOKEN_URL);
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setCorpid(DingTalkConsts.DING_TALK_APP_CORP_ID);
        request.setCorpsecret(DingTalkConsts.DING_TALK_APP_CORP_SECRET);
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        CORP_ACCESS_TOKEN = response.getAccessToken();
        LAST_TIME = curTime;
        return CORP_ACCESS_TOKEN;
    }

    @Override
    public OapiSnsGetPersistentCodeResponse getPersistentCode(String snsAccessToken, String tmpAuthCode) throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_PERSISTENT_CODE+ "?access_token="+snsAccessToken);
        OapiSnsGetPersistentCodeRequest request = new OapiSnsGetPersistentCodeRequest();
        request.setTmpAuthCode(tmpAuthCode);
        request.setHttpMethod("POST");
        OapiSnsGetPersistentCodeResponse response = client.execute(request);
        if (response.isSuccess()) {
            logger.info("请求到的openid={}, persistentCode={}",response.getOpenid(), response.getPersistentCode());
            return response ;
        }
        logger.error("请求永久访问code报错,{}",response.getErrmsg());
        return null;
    }

    @Override
    public String getUserSnsToken(String snsToken, String openId, String persistentCode) throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_SNS_TOKEN_BY_OPENID+ "?access_token="+snsToken);
        OapiSnsGetSnsTokenRequest request = new OapiSnsGetSnsTokenRequest();
        request.setOpenid(openId);
        request.setPersistentCode(persistentCode);
        request.setHttpMethod("POST");
        OapiSnsGetSnsTokenResponse response = client.execute(request);
        if (response.isSuccess()) {
            logger.info("sns_token={}",response.getSnsToken());
            return response.getSnsToken();
        }
        logger.error("请求用户授权SNSToken报错,{}",response.getErrmsg());
        return response.getSnsToken();
    }

    @Override
    public StaffDingTalk getDingTalkResultByuserId(String userId) throws ApiException {
        String assessToken = dingTalkService.getDingTalkAccessToken();

        DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_STAFF_URL);
        OapiSmartworkHrmEmployeeListRequest req = new OapiSmartworkHrmEmployeeListRequest();
        req.setUseridList(userId);
        req.setFieldFilterList(DingTalkConsts.DING_TALK_GET_PARAM);
        OapiSmartworkHrmEmployeeListResponse rsp = client.execute(req, assessToken);


        Map map = JSONObject.parseObject(rsp.getBody(), Map.class);
        if (!Objects.equals(map.get("errcode"), 0)) {
            return null;
        }
        JSONArray jsonArray = JSONObject.parseArray(String.valueOf(map.get("result")));
        Map map1 = JSONObject.parseObject(jsonArray.get(0).toString(), Map.class);
        List<DingTalkResult> dingTalkResultList = JSONObject.parseArray(String.valueOf(map1.get("field_list")), DingTalkResult.class);
        StaffDingTalk staffDingTalk = new StaffDingTalk();
        for (DingTalkResult dingTalkResult : dingTalkResultList) {
            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_REGULARTIME) && Objects.nonNull(dingTalkResult.getValue())) {
                staffDingTalk.setBecomeFormalTime(DateUtil.parse(dingTalkResult.getValue(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_EMPLOYEETYPE) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setRoleType(StaffDict.getRoleTypeByName(dingTalkResult.getLabel()));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_CERTNO) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setIdCardNumber(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_BIRTHTIME) && Objects.nonNull(dingTalkResult.getValue())) {
                staffDingTalk.setBirthday(DateUtil.parse(dingTalkResult.getValue(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_SEXTYPE) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setSexType(StaffFamilyDict.getSexTypeByName(dingTalkResult.getLabel()));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_NATIONTYPE) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setNationType(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_CERTADDRESS) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setIdCardAdress(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_CERTENDTIME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setIdCardValidityTime(DateUtil.parse(dingTalkResult.getLabel(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_MARRIAGE) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setMarriageStatus(StaffArchivesDict.getMarriageStatusByName(dingTalkResult.getLabel()));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_JOINWORKINGTIME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setJoinWorkingTime(DateUtil.parse(dingTalkResult.getLabel(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_RESIDENCETYPE) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setResidenceType(StaffArchivesDict.getResidenceTypeByName(dingTalkResult.getLabel()));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_ADDRESS) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setRegisteredAdress(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_POLITICALSTATUS) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setPoliticalStatus(StaffArchivesDict.getPoliticalStatusByName(dingTalkResult.getLabel()));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_HIGHESTEDU) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setHighestEdu(StaffArchivesDict.getHighestEduByName(dingTalkResult.getLabel()));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_GRADUATESCHOOL) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setGraduateSchool(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_GRADUATIONTIME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setGraduationTime(DateUtil.parse(dingTalkResult.getLabel(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_MAJOR) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setMajor(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_BANKACCOUNTNO) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setBankCardNo(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_FIRSTCONTRACTSTARTTIME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setFristContractTime(DateUtil.parse(dingTalkResult.getLabel(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_FIRSTCONTRACTENDTIME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setFristContractEndTime(DateUtil.parse(dingTalkResult.getLabel(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_NOWCONTRACTSTARTTIME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setContractTimeNow(DateUtil.parse(dingTalkResult.getLabel(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_NOWCONTRACTENDTIME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setContractEndTimeNow(DateUtil.parse(dingTalkResult.getLabel(), DateUtil.FORMAT_DATE));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_CONTRACTRENEWCOUNT) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setContractTimes(Integer.parseInt(dingTalkResult.getLabel()));
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_URGENTCONTACTSNAME) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setFamilyName(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_URGENTCONTACTSPHONE) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setFamilyMobile(dingTalkResult.getLabel());
            }

            if (Objects.equals(dingTalkResult.getField_code(), DingTalkConsts.PARAM_URGENTCONTACTSRELATION) && Objects.nonNull(dingTalkResult.getLabel())) {
                staffDingTalk.setFamilyRelation(StaffFamilyDict.getFamilyByName(dingTalkResult.getLabel()));
            }
        }
        return staffDingTalk;
    }

    @Override
    public ResponseDTO<Boolean> sendDingTalkWorkRecord(String userId, String content) throws ApiException {
        logger.error("发送钉钉消息参数userId" + userId + "; content:" + content);
        String assessToken = dingTalkService.getDingTalkAccessToken();
        DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_SED_WORK_RECORD_MSG_URL);
        OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();

        req.setAgentId(DingTalkConsts.DING_TALK_AGENT_ID);
        req.setUseridList(userId);
        req.setToAllUser(false);
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("text");
        msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
        msg.getText().setContent(content);
        req.setMsg(msg);
        try {
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, assessToken);
            Map map = JSONObject.parseObject(rsp.getBody(), Map.class);
            if (!Objects.equals(map.get("errcode"), "0")) {
                return ResponseDTO.success(true);
            } else {
                logger.error(map.get("errmsg").toString());
                return ResponseDTO.success(false, map.get("errmsg").toString());
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResponseDTO.success(true);
        }

    }

    @Override
    public ResponseDTO<DingTalkLeave> getLeaveStaffMsgByDTalkId(String dTalkId) throws ApiException {
        String assessToken = dingTalkService.getDingTalkAccessToken();
        DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_LEAVE_URL);
        OapiSmartworkHrmEmployeeListdimissionRequest req = new OapiSmartworkHrmEmployeeListdimissionRequest();
        req.setUseridList(dTalkId);
        OapiSmartworkHrmEmployeeListdimissionResponse response = client.execute(req, assessToken);
        logger.info("钉钉返回日志打印：" + response.getBody());

        Map map = JSONObject.parseObject(response.getBody(), Map.class);
        if (!Objects.equals(map.get("errcode"), 0)) {
            return ResponseDTO.fail(121706, "钉钉调用失败");
        }
        JSONArray jsonArray = JSONObject.parseArray(String.valueOf(map.get("result")));

        if(jsonArray.size() == 0){
            return ResponseDTO.fail(121706, "钉钉调用失败");
        }

        JSONObject object = JSONObject.parseObject(jsonArray.get(0).toString());
        if (Integer.parseInt(String.valueOf(object.get("status"))) == 3) {
            return null;
        }
        DingTalkLeave dingTalkLeave = JSONObject.toJavaObject(object, DingTalkLeave.class);

        return ResponseDTO.success(dingTalkLeave);
    }

    @Override
    public String getUnionIdBySnsToken(String snsToken) {
        // 通过临时授权码获取授权用户的个人信息
        DefaultDingTalkClient client2 = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_UNION_ID);
        OapiSnsGetuserinfoRequest request = new OapiSnsGetuserinfoRequest();
        // 通过扫描二维码，跳转指定的redirect_uri后，向url中追加的code临时授权码
        request.setSnsToken(snsToken);
        try {
            OapiSnsGetuserinfoResponse response = client2.execute(request);
            if (response.isSuccess()) {
                logger.info("员工unionId={}", response.getUserInfo().getUnionid());
                return response.getUserInfo().getUnionid();
            } else {
                logger.error("接口getUnionIdByCode 查询unionId报错，错误{}",response.getErrmsg());
                return null;
            }

        } catch (ApiException e) {
            logger.error("调用钉钉接口获取unionId报错", e);
            return null;
        }
    }

    @Override
    public ResponseDTO<String> getUserIdByUnionId(String unionId) throws ApiException {
        String accessToken = getCorpAccessToken();
        DingTalkClient clientDingTalkClient = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_USER_ID);
        OapiUserGetUseridByUnionidRequest reqGetbyunionidRequest = new OapiUserGetUseridByUnionidRequest();
        reqGetbyunionidRequest.setUnionid(unionId);
        OapiUserGetUseridByUnionidResponse oapiUserGetbyunionidResponse = clientDingTalkClient.execute(reqGetbyunionidRequest, accessToken);
        if (oapiUserGetbyunionidResponse.isSuccess()) {
            logger.info("员工userId={}",oapiUserGetbyunionidResponse.getUserid());
            return ResponseDTO.success(oapiUserGetbyunionidResponse.getUserid());
        } else {
            logger.error("接口getUserIdByUnionId 查询userId报错，错误:{}", oapiUserGetbyunionidResponse.getErrmsg());
            return ResponseDTO.fail(oapiUserGetbyunionidResponse.getErrmsg());
        }
    }

    @Override
    public ResponseDTO<String> getUserIdByAuthCode(String authCode) {
        try{
            String accessToken = getCorpAccessToken();
            DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_GET_USER_ID_BY_AUTHCODE);
            OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
            request.setCode(authCode);
            request.setHttpMethod("GET");
            OapiUserGetuserinfoResponse response;
            response = client.execute(request, accessToken);
            logger.info("response = {}", response.getMsg());
            return ResponseDTO.success(response.getUserid());
        } catch (ApiException apiException) {
            logger.error("钉钉接口调用失败", apiException);
            return ResponseDTO.fail("钉钉接口调用失败,错误信息 = {apiException.getMessage()}");
        }
        catch (Exception e) {
            logger.error("登录获取用户信息报错", e);
            return ResponseDTO.fail("登录获取用户信息报错");
        }

    }

    @Override
    public ResponseDTO<Boolean> sendMessageToGroupByRobot(RobotSendGroupMessage message) {

        String url;
        try {
            url = DingTalkConsts.DING_TALK_ROBOT_SEND_URL + "?access_token="+ message.getAccessToken() +"&timestamp=" + System.currentTimeMillis() + "&sign=" + getDingTalkAutoRobotSing(message.getSecret());
        } catch (Exception e) {
            return ResponseDTO.success(false, "机器人发送消息签名计算异常：" + e.getMessage());
        }
        DingTalkClient client = new DefaultDingTalkClient(url);
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("text");
        OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
        text.setContent(message.getContent());
        request.setText(text);
        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setIsAtAll("true");
        request.setAt(at);
        try {
            OapiRobotSendResponse response = client.execute(request);
            JSONObject jsonObject = JSON.parseObject(response.getBody());
            Integer errCode = 0;
            if (errCode.equals(jsonObject.getInteger("errcode"))) {
                return ResponseDTO.success(true);
            } else {
                logger.error("机器人向指定群发送消息失败：" + response.getBody());
                return ResponseDTO.success(false, jsonObject.getString("errmsg"));
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResponseDTO.success(true);
        }
    }

    /**
     * 发送图片消息
     *
     * @param dingTalkIdAndMediaIdList 发送图片消息对象
     * @return  true 发送成功 false 发送失败
     * @author xujie
     * @since 2021/04/28
     */
    @Override
    public ResponseDTO<List<SendImageMessageResult>> sendImageMessage(List<DingTalkIdAndMediaId> dingTalkIdAndMediaIdList) {

        String assessToken;
        try {
            assessToken = dingTalkService.getDingTalkAccessToken();
        } catch (ApiException e) {
            e.printStackTrace();
            logger.error("发送图片消息失败，获取钉钉AccessToken异常：" + e.getMessage(), e);
            return ResponseDTO.fail("发送失败，获取钉钉AccessToken异常：" + e.getMessage());
        }
        DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.DING_TALK_SED_WORK_RECORD_MSG_URL);
        List<SendImageMessageResult> resultList = new ArrayList<>(dingTalkIdAndMediaIdList.size());
        dingTalkIdAndMediaIdList.forEach( d -> {
            OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
            req.setAgentId(DingTalkConsts.DING_TALK_AGENT_ID);
            req.setUseridList(d.getDTalkId());
            req.setToAllUser(false);
            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setMsgtype("image");
            msg.setImage(new OapiMessageCorpconversationAsyncsendV2Request.Image());
            msg.getImage().setMediaId(d.getMediaId());
            req.setMsg(msg);
            try {
                OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, assessToken);
                JSONObject jsonObject = JSON.parseObject(rsp.getBody());
                Integer errCode = 0;
                if (errCode.equals(jsonObject.getInteger("errcode"))) {
                    resultList.add(SendImageMessageResult.builder().staffId(d.getStaffId()).result(GlobalConsts.YES).build());
                } else {
                    logger.error("发送图片消息失败：" + rsp.getBody());
                    resultList.add(SendImageMessageResult.builder().staffId(d.getStaffId()).result(GlobalConsts.NO).build());
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                logger.error("发送图片消息异常：" + e.getMessage(), e);
                resultList.add(SendImageMessageResult.builder().staffId(d.getStaffId()).result(GlobalConsts.NO).build());
            }
        });
        return ResponseDTO.success(resultList, "调用成功");
    }

    /**
     * 机器人发送消息加签
     * @param secret 秘钥
     * @return 签名
     */
    private static String getDingTalkAutoRobotSing(String secret) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {

        Long timestamp = System.currentTimeMillis();
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        return URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");

    }
}
